﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using StackExchange.Redis;
using TianYuan.Core.Caching;
using TianYuan.Utils.Extensions;

namespace TianYuan.Redis.Cache
{
    public class RedisCache : CacheBase
    {
        
        private readonly string _region;
        private readonly RedisClient _cache;
        
        string address;
        JsonSerializerSettings jsonConfig = new JsonSerializerSettings() { ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore, NullValueHandling = NullValueHandling.Ignore };
        /// <summary>
        /// 获取 缓存区域名称，可作为缓存键标识，给缓存管理带来便利
        /// </summary>
        public override string Region
        {
            get { return _region; }
        }

        /// <summary>
        /// 初始化一个<see cref="RuntimeMemoryCache"/>类型的新实例
        /// </summary>
        public RedisCache(string region, RedisClient cache)
        {
            _region = region;
            _cache = cache;
        }

        public override void Clear()
        {
            string cacheKey = string.Concat(_region, ":", "*");
            _cache.DeleteByKeyPattern(cacheKey);
        }

        public override void Clear(string key)
        {
            key.CheckNotNull("key");
            string cacheKey = string.Concat(_region, ":", key, "*");
            _cache.DeleteByKeyPattern(cacheKey);
        }

       
        public override bool Contains(string key)
        {
            key.CheckNotNull("key");
            string cacheKey = GetCacheKey(key);
            bool b = _cache.KeyExists(cacheKey);
            return b;
        }

        public override object ObjectGet(string key)
        {
            var obj = Get<object>(key);
            return obj;
        }

        public override T Get<T>(string key)
        {
            key.CheckNotNull("key");
            string cacheKey = GetCacheKey(key);
            var cacheValue = _cache.StringGet<T>(cacheKey);
            return cacheValue;
            
        }

        public override IEnumerable<object> GetAll()
        {
            throw new NotImplementedException();
        }

        public override IEnumerable<T> GetAll<T>()
        {
            throw new NotImplementedException();
        }

        public override void Remove(string key)
        {
            key.CheckNotNull("key");
            string cacheKey = GetCacheKey(key);
            _cache.KeyDelete(cacheKey);
        }

        public override void Set(string key, object value)
        {
            key.CheckNotNull("key");
            string cacheKey = GetCacheKey(key);
            //var jsonData = GetJsonData(value, TimeOut, false);
            _cache.StringSet(cacheKey, value);
        }

        public override void Set(string key, object value, DateTime absoluteExpiration)
        {
            key.CheckNotNull("key");
            string cacheKey = GetCacheKey(key);
            //var jsonData = GetJsonData(value, TimeOut, true);
            TimeSpan ts = absoluteExpiration - DateTime.Now;
            _cache.StringSet(cacheKey, value, ts);
        }

        public override void Set(string key, object value, TimeSpan slidingExpiration)
        {
            key.CheckNotNull("key");
            string cacheKey = GetCacheKey(key);
            //var jsonData = GetJsonData(value, TimeOut, true);
            _cache.StringSet(cacheKey, value, slidingExpiration);
        }
        #region 私有方法

        private string GetCacheKey(string key)
        {
            return string.Concat(_region, ":", key, "@", key.GetHashCode());
        }
        #endregion
    }
   
}
